package com.example.cato_api.controller;


import com.example.cato_data.data.TacoRepository;
import com.example.cato_entity.entity.Order;
import com.example.cato_entity.entity.Taco;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.EntityLinks;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;


import java.util.List;
import java.util.Optional;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

/*
  启用超媒体 api所返回的资源会包含该资源的相关链接
 */
@RestController // restController注解会告诉spring，控制器中所有的处理器方法的返回值都要直接写入响应体，不
// 是将值放到一个模型传递给视图进行渲染，想当于Controller+ResponseBody
@RequestMapping(path = "/design", produces = "application/json") //produces 说明这个DesignTacoController所有处理器方法
// 只会处理Accept偷包含application/json的请求
@CrossOrigin("*")                                            //允许跨域访问
public class DesignTacoController {

    private TacoRepository tacoRepo;

    @Autowired
    EntityLinks entityLinks;


    public DesignTacoController(TacoRepository tacoRepo) {
        this.tacoRepo = tacoRepo;
    }

    @GetMapping("/recent")
    public Flux<Taco> recentTacos(){
        return tacoRepo.findAll().take(12);
    }

    @GetMapping("/{id}")
    public Mono<Taco> tacoById(@PathVariable("id") Long id){
        return tacoRepo.findById(id);
    }

    @PostMapping(consumes = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    public Mono<Taco> postTaco(@RequestBody Mono<Taco> tacoMono){
        return tacoRepo.saveAll(tacoMono).next(); //saveAll返回FLux，但Flux只会返回一个Taco，调用next返回Mono
    }

//
//    @GetMapping("/recent")
//
//    public Iterable<Taco> recentTacos() {
//        PageRequest page = PageRequest.of(0, 12, Sort.by("createdAt").descending());
//        return tacoRepo.findAll(page).getContent();
//    }
//
//    @GetMapping("/recent")
//    // Resources 已经改名为CollectionModel 代表资源的集合，Resource 改名为 EntityModel吗，为一个资源 都可以携带链接
//    public CollectionModel<EntityModel<Taco>> recentTaco_() {
//        PageRequest page = PageRequest.of(0, 12, Sort.by("createdAt").descending());
//        List<Taco> tacos = tacoRepo.findAll(page).getContent(); // getContent返回一个list
//        CollectionModel<EntityModel<Taco>> recentResources = CollectionModel.wrap(tacos);
//        // wrap 方法将tacos打包成CollectionModel<EntityModel<Taco>>
////     1   recentResources.add(new Link("http://localhost:8080/design/recent","recents"));
////     2   recentResources.add(WebMvcLinkBuilder.linkTo(DesignTacoController.class).slash("recent").withRel("recents"));
//        //WebMvcLinkBuilder 可以自动探知主机名 slash会为url添加斜线和给定的值 ，withRel为这个link起了个名字
//        recentResources.add(linkTo(methodOn(DesignTacoController.class).recentTaco_()).withRel("recents"));
//        // 静态导入两个方法 methodOn 传入控制器类，从而调用这个方法recentTaco_
//        return recentResources;
//    }
//
//    @GetMapping("/recent")
//    public CollectionModel<TacoEntityModel> recentTacos_() {
//        PageRequest page = PageRequest.of(0, 12, Sort.by("createdAt").descending());
//        List<Taco> tacos = tacoRepo.findAll(page).getContent();
//        CollectionModel<TacoEntityModel> recentResources = new TacoEntityModelAssembler().toCollectionModel(tacos); //遍历链表，调用我们重写的toModel方法
//        recentResources.add(linkTo(methodOn(DesignTacoController.class).recentTacos_()).withRel("recents"));
//        //每个taco都有一个self链接，整体有个recents链接
//        return recentResources;
//    }
//
//
//    @GetMapping("/{id}")
//    public ResponseEntity<Taco> tacoById(@PathVariable("id") Long id) {
//        Optional<Taco> optTaco = tacoRepo.findById(id);   //Optional<T> findById(ID var1); 就是findById(Id).get() 即返回T类型
//        if (optTaco.isPresent()) {        //检验值是否存在
//            return new ResponseEntity<>(optTaco.get(), HttpStatus.OK);
//        }
//        return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
//    }
//
//    @PostMapping(consumes = "application/json")  //consumes:指定请求输入，而上面的produces;指定输出
//    @ResponseStatus(HttpStatus.CREATED)
//    public Taco postTaco(@RequestBody Taco taco) {   // @RequestBody 表明请求被转换成一个Taco对象，被绑定在参数上，没有他
//        // spring会认为我们希望将请求参数绑定到Taco上，但是，这个注解能够确保请求体中的json会被绑定在Taco对象中
//        return tacoRepo.save(taco);
//    }


}
